package dao;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;

import entity.Level;
import entity.Risk;

public class RiskDao {
	private static final String risksPath = DataSource.path + "/risks/";
	private static final String riskUserRelationFile=DataSource.path + "/riskUserRelation/relation";
	

	public Risk read(int id) {
		Risk risk = new Risk();
		Properties props = new Properties();
		try {
			InputStream in = new BufferedInputStream(new FileInputStream(risksPath + id));
			props.load(in);
			risk.setId(Integer.parseInt(props.getProperty("id")));
			risk.setCommittedBy(Integer.parseInt(props.getProperty("committedBy")));
			risk.setDescription(props.getProperty("description"));
			risk.setInfluence(Level.stringToLevel(props.getProperty("influence")));
			risk.setPossibility(Level.stringToLevel(props.getProperty("possibility")));
			risk.setTitle(props.getProperty("title"));
			risk.setTracer(Integer.parseInt(props.getProperty("tracer")));
			return risk;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public List<Risk> readAll(int userId) {
		String risks=getValue(Integer.toString(userId),riskUserRelationFile);
		if(risks==null)
			return new LinkedList<>();
		String[] riskIds=risks.split(",");
		List<Risk> result=new LinkedList<>();
		for(String id:riskIds){
			result.add(read(Integer.parseInt(id)));
		}
		
		return result;
	}

	public void write(Risk risk) {
		int id=IDGenerator.id();
		File newRiskFile=new File(risksPath+id);
		while(newRiskFile.exists()){
			id=IDGenerator.id();
			newRiskFile=new File(risksPath+id);
		}
		try {
			newRiskFile.createNewFile();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		Properties props = new Properties();
		try {
			OutputStream fos = new FileOutputStream(newRiskFile);
			props.setProperty("id",Integer.toString(id));
	        props.setProperty("title",risk.getTitle());
	        props.setProperty("committedBy",Integer.toString(risk.getCommittedBy()));
	        props.setProperty("influence",risk.getInfluence().toString());
	        props.setProperty("possibility",risk.getPossibility().toString());
	        props.setProperty("tracer",Integer.toString(risk.getTracer()));
	        props.setProperty("description","");
	        props.store(fos,"create a risk");
		}catch (IOException e) {
			e.printStackTrace();
		}
		appendRiskToUser(id,risk.getTracer());
	}
	
	public void updateRisk(int id,String description){
		Risk risk=read(id);
		Properties props = new Properties();
		try {
			OutputStream fos = new FileOutputStream(risksPath+id);
			props.setProperty("id",Integer.toString(id));
	        props.setProperty("title",risk.getTitle());
	        props.setProperty("committedBy",Integer.toString(risk.getCommittedBy()));
	        props.setProperty("influence",risk.getInfluence().toString());
	        props.setProperty("possibility",risk.getPossibility().toString());
	        props.setProperty("tracer",Integer.toString(risk.getTracer()));
	        props.setProperty("description",description);
	        props.store(fos,"update description");
		}catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void appendRiskToUser(int riskId,int userId){
		Properties props = new Properties();
		String risks=getValue(userId+"",riskUserRelationFile);
		try {
			OutputStream fos = new FileOutputStream(riskUserRelationFile);
			props.setProperty(Integer.toString(userId),risks==null?Integer.toString(riskId):risks+","+riskId);
	        props.store(fos,"create a risk");
		}catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private String getValue(String property,String filename){
		Properties props = new Properties();
		try {
			InputStream in = new BufferedInputStream(new FileInputStream(filename));
			props.load(in);
			return props.getProperty(property);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}
